
import wx,json
import webbrowser
import wx.richtext as rt;
from ctrl.FileDrop import FileDrop

'''
文本编辑Panel
'''
class TxtPanel(wx.Panel):
    def __init__(self,parent,id):
        wx.Panel.__init__(self,parent,id)
        self.app=wx.GetApp()
        self.frame=parent.frame
        # vbox=wx.BoxSizer(wx.VERTICAL) #行分
        vbox=wx.BoxSizer()  #列分
        self.changeState=0

        self.TXResult=rt.RichTextCtrl(self,-1,"",style=wx.HSCROLL|wx.NO_BORDER)
        # self.TXResult=rt.RichTextCtrl(self,textCode,"",style=wx.NO_BORDER)
        # self.TXResult.SetBackgroundColour((199, 237, 204))
        self.TXResult.SetBackgroundColour('#c7edcc')
        # self.TXResult.EnableVerticalScrollbar(False) #关闭滚动条
        self.TXResult.Bind(wx.EVT_TEXT,self.OnPaintMotion)
        self.TXResult.Bind(wx.EVT_KEY_DOWN,self.keyDown)
        self.TXResult.Bind(wx.EVT_LEFT_UP,self.getSelStrCursor) #选择

        #文件拖拽
        dt = FileDrop(self.TXResult)
        self.TXResult.SetDropTarget(dt)

        # 测试处理中
        # self.TXResult.Bind(wx.EVT_SCROLL,  self.OnScroll)
        # self.TXResult.Bind(wx.EVT_SCROLLWIN_LINEUP,  self.OnScroll)
        # self.TXResult.Bind(wx.EVT_SCROLLWIN_LINEDOWN,  self.OnScroll)
        # self.TXResult.Bind(wx.EVT_SCROLLWIN_PAGEUP,  self.OnScroll)
        # self.Bind(wx.EVT_SCROLL, self.OnScroll)
        # self.Bind(wx.EVT_MOTION, self.OnScroll)  #滚动事件
        # self.TXResult.Bind(wx.EVT_SCROLL_CHANGED, self.OnScroll)
        # self.Bind(wx.EVT_SCROLLWIN,self.OnScroll, self.TXResult)

        #~~行号功能~~
        # self.lineNum=rt.RichTextCtrl(self,-1,"1\n2\n3\n",style=wx.NO_BORDER|rt.RE_READONLY,size=(35, -1))
        # font = wx.Font(9, wx.MODERN, wx.NORMAL, wx.NORMAL, False, '微软雅黑')
        # self.lineNum.SetFont(font)
        # self.lineNum.SetBackgroundColour((240, 240, 240))
        # self.lineNum.EnableVerticalScrollbar(False)
        # # ShowPosition
        # vbox.Add(self.lineNum,0,wx.EXPAND)

        vbox.Add(self.TXResult,1,wx.EXPAND)

        self.SetSizer(vbox)

    def OnScroll(self,event):
        print("滚动条位置",event)
        event.Skip()
    
    def keyDown(self,event):
        '''
        键盘监控
        '''
        value=self.TXResult.GetStringSelection()
        keycode = event.GetKeyCode()
        if keycode==45 and wx.GetKeyState(wx.WXK_CONTROL): #减小
            self.frame.changeFontSize(1)
            return
        elif keycode==61 and wx.GetKeyState(wx.WXK_CONTROL): #增大 
            self.frame.changeFontSize()
            return
        elif keycode==9 and wx.GetKeyState(wx.WXK_SHIFT):  #shift + tab
            x = self.TXResult.GetInsertionPoint()
            if value:
                start,end=self.TXResult.GetSelection().GetRanges()[-1].Get()  #获取选择内容
                value=value.replace('    ','')
                self.addDate(start,end+1,value)
                self.TXResult.SetInsertionPoint(x)
            
        elif keycode==9: #tab
            x = self.TXResult.GetInsertionPoint()
            if value:
                start,end=self.TXResult.GetSelection().GetRanges()[-1].Get()  #获取选择内容
                value=value.replace('\n','\n    ')
                value='    '+value
                self.addDate(start,end+1,value)
                self.TXResult.SetInsertionPoint(x+4)
            else:
                self.addDate(x,x,"    ")
                self.TXResult.SetInsertionPoint(x+4)

            return

        elif keycode==8: #删除内容
            if value:
                start,end=self.TXResult.GetSelection().GetRanges()[-1].Get()  #获取选择内容
                self.addDate(start,end+1,"")
                return
            else:
                content = self.TXResult.GetValue()
                len_con=len(content)
                x = self.TXResult.GetInsertionPoint()
                str1 = content[0:x]
                if str1.endswith("    "):
                    self.addDate(x-4,x,"\n")
                    self.TXResult.SetInsertionPoint(x-3)

            event.Skip()

        elif keycode==313: #home
            content = self.TXResult.GetValue()
            len_con=len(content)
            x = self.TXResult.GetInsertionPoint()
            row=content[0:x].split("\n")[-1]

            if row.startswith("    "):
                tmp=self.getSpace(row)

                if len(row)==len(tmp):
                    self.TXResult.SetInsertionPoint(x-len(tmp))
                else:
                    self.TXResult.SetInsertionPoint(x-len(row)+len(tmp))
                return
            else:
                event.Skip()
            
        elif keycode==312: #end
            content = self.TXResult.GetValue()
            # len_con=len(content)
            x = self.TXResult.GetInsertionPoint()
            row=content[x:].split("\n")[0]

            if row.startswith("    "):
                tmp=self.getSpace(row)
                self.TXResult.SetInsertionPoint(x+len(tmp))
                
                return
            else:
                event.Skip()

        elif keycode==13: #换行
            content = self.TXResult.GetValue()
            x = self.TXResult.GetInsertionPoint()
            row=content[0:x].split("\n")[-1]

            if row.startswith("    "):
                tmp=self.getSpace(row)
                self.addDate(x,x,"\n"+tmp)
                self.TXResult.SetInsertionPoint(x+len(tmp)+1)
                # self.TXResult.ScrollIntoView(len(content)+4, 0)
                return
            else:
                event.Skip()

        elif keycode==76 and wx.GetKeyState(wx.WXK_CONTROL): #复制行
            self.copyLine()
            return

        elif keycode ==68 and wx.GetKeyState(wx.WXK_CONTROL): #删除行
            self.delLine()
            return

        else:
            if value:
                self.changeFont(self.app.fontSize)
            event.Skip()

    def jsonFormat(self):
        '''
        json格式化
        '''
        value=self.TXResult.GetStringSelection()
        if value:
            start,end=self.TXResult.GetSelection().GetRanges()[-1].Get()  #获取选择内容
            try:
                jsonStr = json.dumps(json.loads(value), ensure_ascii=False,sort_keys=True, indent=4, separators=(',', ': '))
                self.addDate(start,end+1,jsonStr)
            except BaseException as exception:
                wx.MessageBox(str(exception), 'json转换异常',wx.OK|wx.ICON_WARNING)

        else:
            context=self.TXResult.GetValue()
            try:
                jsonStr = json.dumps(json.loads(context), ensure_ascii=False,sort_keys=True, indent=4, separators=(',', ': '))
                self.addDate(0,len(context),jsonStr)
            except BaseException as exception:
                wx.MessageBox(str(exception), 'json转换异常',wx.OK|wx.ICON_WARNING)

    def getSpace(self,row):
        '''
        获取当行空格数
        '''
        num=0
        step="    "
        tmp="    "
        while True:
            if not row.startswith(tmp):
                tmp=tmp[0:len(tmp)-4]
                break
            tmp+=step
        return tmp

    def toLine(self):
        '''
        数据多行转一行
        '''
        value=self.TXResult.GetStringSelection()
        if value:
            start,end=self.TXResult.GetSelection().GetRanges()[-1].Get()  #获取选择内容
            value=value.replace("\n","")
            self.addDate(start,end+1,value)
        else:
            context=self.TXResult.GetValue()
            tmp=context.replace("\n","")
            self.fxnotebook.getTab().addDate(0,len(context),tmp)

    def getSelStrCursor(self,event):
        '''
        选择内容
        '''
        value=self.TXResult.GetStringSelection()
        if value:
            self.changeFont(self.app.fontSize)  #重置字体样式，修复状态异常
            
            #重置样式
            context=self.TXResult.GetValue().upper()
            lenSize=len(context)
            font = wx.Font(self.app.fontSize,wx.MODERN, wx.NORMAL, wx.NORMAL, False,faceName='微软雅黑')
            findstr=value.upper()
            attr=wx.TextAttr(wx.NullColour, wx.Colour(116, 198, 34),font)

            index=0
            while True:
                found = context.find(findstr,index,lenSize)
                if found != -1:
                    end = found + len(findstr)
                    self.TXResult.SetStyle(found,end,attr)

                    index=end
                else:
                    break
            self.changeState=1
        else:
            if self.changeState==1:
                self.changeFont(self.app.fontSize)

        event.Skip()

    def changeFont(self,size):
        '''
        重置字体大小
        '''
        #设置新内容字体
        # self.TXResult.BeginFontSize(size)
        
        #旧内容设置字体
        context=self.TXResult.GetValue()
        lenSize=len(context)
        font = wx.Font(size,wx.MODERN, wx.NORMAL, wx.NORMAL, False,faceName='微软雅黑')
        attr=wx.TextAttr(wx.NullColour, wx.Colour(199, 237, 204),font)
        self.TXResult.SetStyle(0,lenSize,attr)
        self.TXResult.SetDefaultStyle(attr)
        self.changeState=0

    def addDate(self,start,end,context):
        '''
        替换数据
        '''
        self.TXResult.Replace(start,end,context)
        self.changeFont(self.app.fontSize)  #重置字体样式，修复状态异常

    def delLine(self):
        '''
        删除本行
        '''
        content = self.TXResult.GetValue()
        len_con=len(content)
        x = self.TXResult.GetInsertionPoint()
        if "\n" in content:
            str1 = content[0:x]
            str2= content[x:len_con]

            if "\n" in str1:
                start=str1.split('\n')[-1]
                end=str2.split('\n')[0]

                startPoint=x-len(start)-1
                endPoint=x+len(end) 
            
            else:
                startPoint=0
                end=str2.split('\n')[0]
                if len(str1)==0:
                    endPoint=len(end)+1
                
                else:
                    endPoint=len(end)+len(str1)+1
            
            self.addDate(startPoint,endPoint,"")

            if  startPoint+2<len(self.TXResult.GetValue()):
                self.TXResult.SetInsertionPoint(startPoint+1)
            else:
                self.TXResult.SetInsertionPoint(startPoint)

        else:
            self.addDate(0,len_con,"")
    
    #超过10 设置25,100 设置30  1000 设置35 以此类推
    def reSizeLineNum(self):
        # '''
        # 刷新行号 
        # '''
        allLine=self.TXResult.GetNumberOfLines()
        # if allLine>=100:
        #     self.lineNum.SetSize(30,-1)
        # elif allLine>=1000:
        #     self.lineNum.SetSize((35,-1))
        # elif allLine>10000:
        #     self.lineNum.SetSize(40,-1)

        lineSize=self.lineNum.GetNumberOfLines()

        if allLine != lineSize-1:
            print(allLine,lineSize)
            line=self.getLineNum()
            content=''
            lenSize=0
            for num in range(allLine):
                if content !='':
                    content+='\n'

                content+=str(num+1)
                if num+1==line:
                    print("设置行: ",line)
                    lenSize=len(content)

            self.lineNum.Freeze()
            self.lineNum.BeginSuppressUndo()

            self.lineNum.SetValue("")
            self.lineNum.BeginAlignment(wx.TEXT_ALIGNMENT_CENTRE)
            self.lineNum.WriteText(content+"\n")
            self.lineNum.EndAlignment()

            self.lineNum.EndSuppressUndo()
            self.lineNum.Thaw()

        # self.lineNum.SetSelection(0,len(content))
        # self.lineNum.IsSelectionAligned(wx.TEXT_ALIGNMENT_CENTRE)
            # value=self.lineNum.ScrollLines(line)
            # print(value)
            value=self.lineNum.ScrollIntoView(lenSize, 1)
            print("set",lenSize,"value",value)
        
    def copyLine(self):
        '''TextPanel.py
        复制本行
        '''
        content = self.TXResult.GetValue()
        len_con=len(content)
        x = self.TXResult.GetInsertionPoint()
        str1 = content[0:x]
        str2= content[x:len_con]
        start=str1.split('\n')[-1]
        end=str2.split('\n')[0]

        content="\n"+start+end

        startPoint=x+len(end)
        self.addDate(startPoint,startPoint,content)
        self.TXResult.SetInsertionPoint(startPoint+len(content))

    def OnPaintMotion(self,event):
        '''
        状态栏修改 
        '''
        if hasattr(self, 'frame') and hasattr(self.frame, 'fxnotebook'):
            self.frame.fxnotebook.changeFileState()
            self.changeStatus()  #更新状态栏
            self.frame.fxnotebook.SaveData()  #保存数据

            # self.reSizeLineNum()#重置滚动条位置

    def getLineNum(self):
        ''' 
        获取行数
        ''' 
        x = self.TXResult.GetInsertionPoint()
        content =  self.TXResult.GetValue()[0:x]
        if "\n" in content:
            line=len(content.split("\n"))
        else:
            line=1
        return line

    def changeStatus(self):
        ''' 
        更改状态栏信息
        ''' 
        allLine=self.TXResult.GetNumberOfLines()
        value= self.TXResult.GetValue()
        num=len(value.strip())
        line=self.getLineNum()
        
        self.frame.SetStatusText('{}/{}行 {}字 '.format(line,allLine,num),1)    
